#include <iostream>
#include <memory>
#include <pthread.h>
#include <map>
#include <string>
#include <functional>

using namespace std;

class Stock
{};
class MutexLock;
class MutexLockGuard
{};

class StockFactory : public std::enable_shared_from_this<StockFactory>
{
public:
    shared_ptr<Stock> get(const string &key)
    {
        shared_ptr<Stock> pStock;
        MutexLockGuard lock(mutex_);
        weak_ptr<Stock>& wkStock = stocks_[key];
        pStock = wkStock.lock();
        if (pStock == nullptr)
        {
            pStock.reset(new Stock,
                    std::bind(&StockFactory::weakDeleteCallback,
                        weak_ptr<StockFactory>(shared_from_this()),
                        _1));
            wkStock = pStock;
        }

        return pStock;
    }

private:
    static void weakDeleteCallback(const weak_ptr<StockFactory> &wkFactory,
                                    Stock *stock)
    {
        shared_ptr<StockFactory> factory(wkFactory.lock());
        if (factory)
        {
            factory->removeStock(stock);
        }
        delete stock;
    }

    void removeStock(Stock *stock)
    {
        if (stock)
        {
            MutexLockGuard lock(mutex_);
            //stocks_.erase(stock);
        }
    }

private:
    mutable MutexLock mutex_;
    std::map<string, weak_ptr<Stock> > stocks_;
};
